package com.pisolution.actuator.client.registration;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.event.EventListener;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 用于创建 {@link Application}.
 *
 * @author sora
 * @version 0.1.0
 */
public abstract class ApplicationFactory {
    /** 用于读取应用名称等信息. */
    private final ApplicationConfig config;

    /** 用于获取应用启动端口等信息. */
    private final ServerProperties server;

    /** 用于记录服务端口. */
    protected Integer port = 8080;

    // -------------------------------------------------------------------------------------------------
    //  初始化
    // -------------------------------------------------------------------------------------------------

    public ApplicationFactory(final ApplicationConfig config, final ServerProperties server) {
        this.config = config;
        this.server = server;
    }

    // -------------------------------------------------------------------------------------------------
    //  应用信息
    // -------------------------------------------------------------------------------------------------

    /**
     * 创建应用数据实体.
     *
     * @return 应用数据实体对象.
     */
    public Application create() {
        return new Application(
            this.config.getName(),
            StringUtils.isBlank(this.config.getEndpoint()) ? this.getEndpoint() : this.config.getEndpoint()
        );
    }

    public abstract String getEndpoint();

    // -------------------------------------------------------------------------------------------------
    //  服务信息
    // -------------------------------------------------------------------------------------------------

    /**
     * 获取协议名称.
     *
     * @return 协议名称.
     */
    protected String getScheme() {
        return this.server.getSsl() == null || !this.server.getSsl().isEnabled() ? "http" : "https";
    }

    /**
     * 获取主机地址.
     *
     * @return 主机地址.
     */
    protected String getHost() {
        InetAddress address = this.server.getAddress();
        if (address == null) {
            try {
                address = InetAddress.getLocalHost();
            } catch (UnknownHostException e) {
                throw new IllegalArgumentException(e.getMessage(), e);
            }
        }

        return address.getHostAddress();
    }

    /**
     * 获取服务端口.
     *
     * @param event 服务初始化事件.
     */
    @EventListener
    public void onWebServerInitialized(WebServerInitializedEvent event) {
        final String name = event.getApplicationContext().getServerNamespace();
        if ("server".equals(name) || StringUtils.isBlank(name)) {
            this.port = event.getWebServer().getPort();
        }
    }
}
